package org.easyframework.frm.excel.cfg;

import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.easyframework.frm.cfg.Column;
import org.easyframework.frm.cfg.Configuration;
import org.easyframework.frm.cfg.DataType;
import org.easyframework.frm.cfg.PersistentObject;
import org.easyframework.frm.exception.FRMException;

public class ExcelObject implements PersistentObject {

	private final Workbook workbook;

	private final String template;

	private Configuration configuration;

	public ExcelObject(Workbook workbook, String template) {
		super();
		this.workbook = workbook;
		this.template = template;
	}

	public boolean hasNext() {
		return workbook.getSheetAt(0).rowIterator().hasNext();
	}

	public Object[] next() throws FRMException {

		if (configuration == null) {
			throw new FRMException("Configuration can not be null", null);
		}

		Row row = workbook.getSheetAt(0).rowIterator().next();

		Object[] values = new Object[row.getLastCellNum()];

		List<Column> columns = configuration.columns();

		for (int i = 0; i < columns.size(); i++) {

			Column column = columns.get(i);

			int index = column.getIndex();

			Cell cell = row.getCell(index);

			values[i] = getValue(cell, column.getDataType());

		}

		return values;
	}

	private Object getValue(final Cell cell, final String displayType) {

		final DataType type = DataType.getByDisplayType(displayType);

		try {

			if (type == DataType.STRING) {

				return cell.getStringCellValue();

			} else if (type == DataType.INT) {

				return (int) cell.getNumericCellValue();

			} else if (type == DataType.DOUBLE) {

				return cell.getNumericCellValue();

			} else if (type == DataType.DATE) {

				return cell.getDateCellValue();

			}

		} catch (Exception e) {

			if (configuration.isContinueOnError()) {

				return type.getDefaultValue();

			}

			throw new FRMException(e.getMessage(), e);

		}

		if (configuration.isInsertEmptyForNull()) {

			return type.getDefaultValue();

		}

		return null;
	}

	public void remove() {
		throw new RuntimeException();
	}

	public String getTemplate() {
		return template;
	}

	public void setConfiguration(Configuration configuration) {
		this.configuration = configuration;
	}

	public String getInsertStatement() {
		return null;
	}

}
